<?php

namespace App\Jobs;

use App\Http\Controllers\Chanjet\TplusCommonController;
use App\Models\Manger\Manger;
use App\Models\Settle\SettleCompany;
use App\Services\Chanjet\ChanjetRequest;
use App\Services\Chanjet\LogFormatRecord;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class Custom implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $data;
    public $tries = 3;      // Laravel 自动重试次数（包括首次执行）
    public $timeout = 60;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function handle()
    {
        $data = $this->data;
        try {
            // 参数校验
            if (!isset($data["mangerinfo"], $data["api"], $data["param"])) {
                throw new \InvalidArgumentException("缺少必要参数: mangerinfo/api/param");
            }
            // 检查是否允许请求
            if (!TplusCommonController::isAllowRequestTplus($data["mangerinfo"])) {
                throw new \InvalidArgumentException("Chanjet API 请求被禁止");
            }
            // 执行 API 请求
            $api = $data["api"];
            $chanjet_params = $this->getProviderCustomerParams($data['param']);
            $res = ChanjetRequest::getInstance()->$api($chanjet_params, $data["mangerinfo"]['org_id']);

            // 处理不同 API 的响应
            $this->validateApiResponse($api, $res);

            Log::info("Chanjet 往来单位客户/供应商同步成功", ['data' => $data]);
        } catch (\Throwable $e) {
            $this->handleFailure($e);
        }
    }

    /**
     *  WarehouseCreate
     *
     *
     */
    protected function validateApiResponse(string $api, $response)
    {
        switch ($api) {
            case "partnerCreate": //67
                if (isset($response["code"])) {
                    throw new \RuntimeException("Chanjet {$api} 请求失败");
                }
                break;
        }
    }

    protected function handleFailure(\Throwable $e)
    {
        // 参数错误立即失败，不重试
        if ($e instanceof \InvalidArgumentException) {
            $this->failed($e);
            return;
        }

        // 可重试错误：达到最大尝试次数后标记失败
        if ($e instanceof \RuntimeException) {
            if ($this->attempts() >= $this->tries) {
                $this->failed($e);
            }else{
                throw $e;
            }
        }
    }

    public function failed(\Throwable $exception)
    {
        // 静默记录日志（非 error 级别）
        Log::info($exception->getMessage().'failed方法');
        $this->data["error"] = $exception->getMessage();
        $this->data["res"] = "Chanjet 往来单位-客户/供应商,同步失败";
        LogFormatRecord::error($this->data);
        return;
    }


    public function getProviderCustomerParams($data){
        $Partner = $this->getProviderCustomerPartner($data['category']);
        $PartnerBankInfoDTOs = $this->getPartnerBankinfoDtos($data);
        $PartnerAddresDTOs = $this->getPartnerAddresDTOs($data);
        $settleCompanyName = SettleCompany::where('id',$data["settlement_company"])->value("settle_company_name");

        $Manger = Manger::where('id',$data["manger_id"])->first();

        if(empty($Manger["code_no"])){ //分管人员必须存在
            throw new \RuntimeException("Chanjet partnerCreate 请求失败,分管人员必须存在");
        }

        $dto = [
            "dto"=>[
                "Code"=>$data["company_code"],
                "Name"=>$data["manger_name"].'_'.$data["company_name"].'_'.$settleCompanyName,//业务员（登录人员）-客户名称-结算公司
                "PartnerType"=>["Code"=>$Partner['partnerTypeCode']],
                "PartnerClass"=>["Code"=>$Partner['PartnerClassCode']],
                "TaxRate" => ["Name" => "0"],
                "SaleMan" => ["Code" => $Manger["code_no"]],//分管人员编码
            ]
        ];
        if(!empty($Manger["sys_dpm_id"])){
            $dto["dto"]["SaleDepartment"]["code"] = $Manger["sys_dpm_id"];
        }
        //$payment_info = json_decode($data["payment_info"],true);
        if($data['category'] == '1'){
            $dto["dto"]["PartnerBankInfoDTOs"]["DynamicPropertyKeys"] = ["priuserdefnvc1","priuserdefnvc2"];
            $dto["dto"]["PartnerBankInfoDTOs"]["DynamicPropertyValues"] = [$data["wechat_number"],$data["account_name"]];
        }
        if($data['category'] == '2'){
            $dto["dto"]["PartnerBankInfoDTOs"]["DynamicPropertyKeys"] = ["priuserdefnvc1","priuserdefnvc2"];
            $dto["dto"]["PartnerBankInfoDTOs"]["DynamicPropertyValues"] = [$data["wechat_number"],$data["account_name"]];
        }
        if(!empty($PartnerBankInfoDTOs)){
            $dto["dto"]["PartnerBankInfoDTOs"] = $PartnerBankInfoDTOs;
        }
        if(!empty($PartnerAddresDTOs)){
            $dto["dto"]["PartnerAddresDTOs"] = $PartnerAddresDTOs;
        }
        return $dto;
    }
    //往来单位分类编码
    public function getProviderCustomerPartner($category)
    {
        if ($category == 1) { //客户
            $partnerClassCode = ChanjetRequest::getInstance()->partnerClassQuery(["param" => ["Name" => "结算客户"]], $this->data["mangerinfo"]['org_id']);
            $partnerType = "01";
            if (empty($partnerClassCode)) {
                //创建分类后，返回null
                $resData = ChanjetRequest::getInstance()->partnerClassCreate(["dto" => ["code" => "settle_customer", "name" => "结算客户"]], $this->data["mangerinfo"]['org_id']);
                $this->validateApiResponse("partnerClassCreate",$resData);
                $partnerClassCode = ChanjetRequest::getInstance()->partnerClassQuery(["param" => ["Name" => "结算客户"]], $this->data["mangerinfo"]['org_id']);
            }
        }

        if ($category == 2) { //供应商
            $partnerClassCode = ChanjetRequest::getInstance()->partnerClassQuery(["param" => ["Name" => "供应商"]], $this->data["mangerinfo"]['org_id']);
            $partnerType = "00";
            if (empty($partnerClassCode)) {
                //创建分类后，返回null
                $resData = ChanjetRequest::getInstance()->partnerClassCreate(["dto" => ["code" => "provider", "name" => "供应商"]], $this->data["mangerinfo"]['org_id']);
                $this->validateApiResponse("partnerClassCreate",$resData);
                $partnerClassCode = ChanjetRequest::getInstance()->partnerClassQuery(["param" => ["Name" => "供应商"]], $this->data["mangerinfo"]['org_id']);
            }
        }
        //查询客户/供应商 分类编码失败
        if(!isset($partnerClassCode) || !isset($partnerClassCode[0]) || !isset($partnerClassCode[0]['Code'])){
            throw new \RuntimeException("Chanjet partnerCreate 请求失败,T+查询/创建客户/供应商分类编码失败");
        }
        return ["partnerTypeCode" => $partnerType, "PartnerClassCode" => $partnerClassCode[0]["Code"]];
    }
    //获取供应商银行信息
    public function getPartnerBankinfoDtos($data){
        $res = [];
        if(isset($data['bank_info'])){
            $bankInfo = json_decode($data['bank_info'], true);
            foreach ($bankInfo as $item) {
                //$this->createBankAccount($item);//忽略错误 直接创建
                $res[] = [
                    "PartnerAccbank" => ["Name"=>$item["bank"]],//开户银行名称
                    "PartnerBankAccount" => $item["bank_card_no"],//账号
                    "IsDefaultBank" => $item["is_default"]=='1'? true : false,//是否默认银行账号
                    "Status" => "1",//1：新增 2：修改 3：删除
                ];
            }
        }
        return $res;
    }
    //获取供应商联系方式
    public function getPartnerAddresDTOs($data){
        $res = [];
        if(isset($data['bank_info'])){
            $bankInfo = json_decode($data['bank_info'], true);
            foreach ($bankInfo as $item) {
                $res[] = [
                    "Contact" => $item["contacts"],//开户银行名称
                    "TelephoneNo" => $item["phone_number"],//地址简称
                    "IsDefaultBank" => $item["is_default"]=='1'? true : false,//是否默认地址
                    "Status" => "1",//1：新增 2：修改 3：删除
                ];
            }
        }
        return $res;
    }
}
